﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace QuotationService
{
    /// <summary>
    /// 用于性能测试的时间计数器类
    /// </summary>
    internal class ProcessTime : IDisposable
    {
        private Stopwatch sw;

        private TimeSpan tsStart;

        /// <summary>
        /// 本次测试的主题
        /// </summary>
        private string title = "";

        /// <summary>
        /// CPU使用（占用）时间(ms)
        /// 只包括本进程的耗时
        /// </summary>
        private double CpuTime = 0;

        /// <summary>
        /// 实际耗时(ms)
        /// 包括操作系统中其他线程/进程的切换、耗时等
        /// </summary>
        private double RealTime = 0;

        /// <summary>
        /// 最大允许耗时毫秒阀值
        /// 耗时超过此数的，将输出调试信息；耗时小于此数的，将自动忽略输出（ignore=true）
        /// </summary>
        private int ThresholdMilliseconds = 0;

        public ProcessTime(int thresholdMilliseconds = 0)
            : this(string.Empty, thresholdMilliseconds)
        {
        }

        public ProcessTime(string title, int thresholdMilliseconds = 0)
        {
            this.title = title;
            this.ThresholdMilliseconds = thresholdMilliseconds;
            Reset();
        }

        ~ProcessTime()
        {
            if (sw.IsRunning)
            {
                Stop();
            }
        }

        public void Dispose()
        {
            if (sw.IsRunning)
            {
                Stop();
            }
        }


        /// <summary>
        /// 重置计时器
        /// </summary>
        public void Reset()
        {
            if (sw != null && sw.IsRunning)
                sw.Stop();

            sw = Stopwatch.StartNew();
            tsStart = Process.GetCurrentProcess().TotalProcessorTime;
        }

        /// <summary>
        /// 重置计数器（包括主题）
        /// </summary>
        /// <param name="title"></param>
        public void Reset(string title)
        {
            if (sw != null && sw.IsRunning)
                sw.Stop();

            this.title = title;
            sw = Stopwatch.StartNew();
            tsStart = Process.GetCurrentProcess().TotalProcessorTime;
        }

        /// <summary>
        /// 计时器停止
        /// </summary>
        public void Stop()
        {
            CpuTime = Process.GetCurrentProcess().TotalProcessorTime.Subtract(tsStart).TotalMilliseconds;

            sw.Stop();
            RealTime = sw.ElapsedMilliseconds;

            if (RealTime >= ThresholdMilliseconds)
            {
                if (Logger.LogService != null)
                {
                    Logger.LogService.LogDebugMsg(this.ToString());
                }
                else
                {
                    Trace.WriteLine(this.ToString());
                }
            }
        }

        /// <summary>
        /// 在不停止计时器的情况下，获取当前的耗时数据
        /// </summary>
        public void Calculate()
        {
            CpuTime = Process.GetCurrentProcess().TotalProcessorTime.Subtract(tsStart).TotalMilliseconds;
            RealTime = sw.ElapsedMilliseconds;
        }


        public override string ToString()
        {
            if (!string.IsNullOrEmpty(title))
                return string.Format("{2}  ----  CPU耗时：{0} ms，实际耗时：{1} ms。", CpuTime, RealTime, title);
            else
                return string.Format("CPU耗时：{0} ms，实际耗时：{1} ms。", CpuTime, RealTime);
        }

    }
}
